package com.chaber.containers.presenters;

import java.text.DateFormat;
import java.text.ParseException;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.util.StringUtils;

import com.chaber.containers.beans.ProductData;
import com.chaber.containers.common.ConstraintViolationEvent;
import com.chaber.containers.services.ProductService;
import com.chaber.containers.views.ProductAddModRemView;
import com.chaber.containers.views.ProductListView;

public class ProductAddModRemPresenter extends AbstractPresenter implements ApplicationListener<ConstraintViolationEvent<ProductData>> {

	@Autowired
	private ProductAddModRemView productAddModRemView;

	@Autowired
	private ProductListView productListView;
	
	@Autowired
	private ProductService productService;
	
	@Override
	public void bindViewActions() {
		this.productListView.getProductsTable().setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent mouseEvent) {
				if (mouseEvent.getButton().equals(MouseButton.PRIMARY) 
						&& mouseEvent.getClickCount() == 2
						&& productListView.getProductsTable().getSelectionModel().selectedItemProperty() != null) {

					ProductData selectedData = productListView.getProductsTable().getSelectionModel().getSelectedItem();

					readProductDetails(selectedData.getBarCode());
				}
			}
		});
		
		this.productListView.getAddButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent evt) {
				initAddProduct();
			}
		});

		this.productAddModRemView.getSaveButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				saveProduct();
			}
		});

		this.productAddModRemView.getInitModifyButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				productAddModRemView.activateEdition();
				productAddModRemView.getBarCodeField().setDisable(true);
			}
		});
		
		this.productAddModRemView.getRemoveButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				removeProduct();
			}
		});
	}

	@Override
	public void onApplicationEvent(ConstraintViolationEvent<ProductData> event) {
		this.prepareValidationErrors(event, this.productAddModRemView.getErrorsBox());
	}
	
	private void readProductDetails(String barCode) {
		this.productAddModRemView.clearFields();
		
		ProductData pData = this.productService.getProduct(barCode);
		this.populateProductDataToTheView(pData);

		this.productAddModRemView.getCategoryComboBox().setItems(this.productListView.getCatField().getItems());
		
		this.productAddModRemView.deactivateEdition();
		this.productAddModRemView.show();
	}

	private void initAddProduct() {
		this.productAddModRemView.clearFields();
		
		this.productAddModRemView.getCategoryComboBox().setItems(this.productListView.getCatField().getItems());
		
		this.productAddModRemView.activateEdition();
		this.productAddModRemView.show();
	}
	
	private void saveProduct() {
		ProductData productToSave = this.populateProductDataFromView();
		this.productService.save(productToSave);
		
		this.readProductDetails(productToSave.getBarCode());
	}
	
	private void removeProduct() {
		String productBarCodeToRemove = this.productAddModRemView.getBarCodeField().getText();
		
		this.productService.remove(productBarCodeToRemove);
		this.productAddModRemView.close();
	}
	
	private ProductData populateProductDataFromView() {
		ProductData productData = applicationContext.getBean(ProductData.class);

		productData.setBarCode(this.productAddModRemView.getBarCodeField().getText());
		productData.setName(this.productAddModRemView.getNameField().getText());
		if (!StringUtils.isEmpty(this.productAddModRemView.getAmountField().getText())) {
			productData.setAmount(Integer.valueOf(this.productAddModRemView.getAmountField().getText()));
		} 
		
		DateFormat df = DateFormat.getDateInstance();
		if (!StringUtils.isEmpty(this.productAddModRemView.getCdField().getText())) {
			try {
				productData.setCreationDate(df.parse(this.productAddModRemView.getCdField().getText()));
			} catch (ParseException e) {
				System.out.println(e.getMessage());
			}
		}

		if (!StringUtils.isEmpty(this.productAddModRemView.getMdField().getText())) {
			try {
				productData.setModificationDate(df.parse(this.productAddModRemView.getMdField().getText()));
			} catch (ParseException e) {
				System.out.println(e.getMessage());
			}
		}
		
		productData.setAssignedCategory(this.productAddModRemView.getCategoryComboBox().getValue());
		
		return productData;
	}

	private void populateProductDataToTheView(ProductData productData) {
		this.productAddModRemView.getBarCodeField().setText(productData.getBarCode());
		this.productAddModRemView.getNameField().setText(productData.getName());
		this.productAddModRemView.getAmountField().setText(productData.getAmount() != null ? productData.getAmount().toString() : null);
		this.productAddModRemView.getCdField().setText(productData.getCreationDate() != null ? productData.getCreationDate().toString() : null);
		this.productAddModRemView.getMdField().setText(productData.getModificationDate() != null ? productData.getModificationDate().toString() : null);
		
		if (productData.getAssignedCategory() != null) {
			this.productAddModRemView.getCategoryComboBox().getSelectionModel().select(productData.getAssignedCategory());
		}
	}
}
